package handler

import (
	"github.com/gin-gonic/gin"
	"github.com/lab-online/internal/class/constant"
	"github.com/lab-online/internal/class/entity"
	"github.com/lab-online/internal/shared/valueobject"
	"github.com/lab-online/pkg/auth"
	mw "github.com/lab-online/pkg/middleware"
	"github.com/lab-online/pkg/resp"
	"github.com/lab-online/pkg/util"
)

type GetClassReqParam struct {
	ClassID uint `uri:"id" binding:"required" example:"1"` // 班级ID
}

var GetClassValidator = mw.NewValidator(func() *mw.ValidatorOptions {
	return &mw.ValidatorOptions{
		Params: &GetClassReqParam{},
	}
})

// TODO 聚合 course
type getClassRespData struct {
	ID          uint          `json:"id" binding:"required"`          // 班级ID
	Name        string        `json:"name" binding:"required"`        // 班级名称
	Teacher     *teacherInfo  `json:"teacher" binding:"required"`     // 教师工号
	Description string        `json:"description" binding:"required"` // 班级介绍
	Students    []studentInfo `json:"students" binding:"required"`    // 学生列表
	CourseID    uint          `json:"courseID" binding:"required"`    // 课程ID
}

type GetClassRespBody struct {
	Data getClassRespData `json:"data" binding:"required"`
	resp.BaseRespBody
}

// GetClass 查询班级详情
//
//	@Summary				查询班级详情
//	@Description.markdown	GetClass
//	@Description			教师可以查询自己班级的学生列表，管理员可以查询任何班级的学生列表
//	@Tags					class
//	@Accept					json
//	@Produce				json
//	@Security				bearer
//	@Param					Authorization	header		string	true	"`teacher` | `admin`"
//	@Param					class			path		string	true	"班级ID"
//	@Success				200				{object}	GetClassRespBody
//	@Failure				400				{object}	resp.FailedRespBodyString
//	@Failure				403				{object}	resp.FailedRespBodyString
//	@Failure				500				{object}	resp.FailedRespBodyString
//	@x-apifox-status		"testing"
//	@Router					/v1/classes/:id [get]
func (h *Handler) GetClass(c *gin.Context) {
	classID := c.MustGet(mw.KeyParams).(*GetClassReqParam).ClassID
	authEntity := c.MustGet(auth.KeyAuth).(auth.AuthEntity)

	classEntity := entity.NewClassEntity(entity.WithID(classID))

	if class, err := h.domain.GetClass(classEntity, authEntity); err != nil {
		resp.ErrorHandler(c, err)
	} else {
		resp.Success(c, constant.CodeGetClassSuccess, &getClassRespData{
			ID:          class.GetID(),
			Name:        class.GetName(),
			CourseID:    class.GetCourseID(),
			Description: class.GetDescription(),
			Teacher: &studentInfo{
				Username: class.GetTeacher(),
				Role:     class.GetTeacherVO().GetRole(),
				Name:     class.GetTeacherVO().GetName(),
			},
			Students: util.SliceMap(class.GetStudentVOs(),
				func(student valueobject.UserVO) studentInfo {
					return studentInfo{
						Name:     student.GetName(),
						Username: student.GetUsername(),
						Role:     student.GetRole(),
					}
				},
			),
		})
	}
}
